using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using RestSharp;

namespace Catastrophe.Common.Http
{
	public class HttpUtil
	{
		public static HttpWebResponse CreateGetHttpResponse(string url, string cotentType = "application/x-www-form-urlencoded")
		{
			HttpWebRequest httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
			if (httpWebRequest != null)
			{
				httpWebRequest.Method = "GET";
				httpWebRequest.ContentType = cotentType;
				return httpWebRequest.GetResponse() as HttpWebResponse;
			}
			return null;
		}

		public static string GetResponseString(HttpWebResponse webresponse)
		{
			using Stream stream = webresponse.GetResponseStream();
			StreamReader streamReader = new StreamReader(stream ?? throw new InvalidOperationException(), Encoding.UTF8);
			return streamReader.ReadToEnd();
		}

		public static string HttpGet(string url, Encoding encoding = null)
		{
			WebClient webClient = new WebClient
			{
				Encoding = (encoding ?? Encoding.UTF8)
			};
			return webClient.DownloadString(url);
		}

		public static string HttpGet(string url, int Timeout)
		{
			try
			{
				HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
				httpWebRequest.KeepAlive = false;
				httpWebRequest.Method = "GET";
				httpWebRequest.ContentType = "text/html;charset=UTF-8";
				httpWebRequest.UserAgent = null;
				httpWebRequest.Timeout = Timeout;
				HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
				Stream responseStream = httpWebResponse.GetResponseStream();
				StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
				string result = streamReader.ReadToEnd();
				streamReader.Close();
				responseStream.Close();
				httpWebRequest.Abort();
				httpWebResponse.Close();
				return result;
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		public static string HttpPost(string url, string body)
		{
			byte[] bytes = Encoding.UTF8.GetBytes(body);
			WebClient webClient = new WebClient();
			webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
			webClient.Headers.Add("ContentLength", bytes.Length.ToString());
			byte[] bytes2 = webClient.UploadData(url, "POST", bytes);
			return Encoding.ASCII.GetString(bytes2);
		}

		public static string HttpPost(string url, string body, string contentType, int timeout = 20000)
		{
			string result = string.Empty;
			HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
			httpWebRequest.Method = "POST";
			httpWebRequest.ContentType = contentType;
			httpWebRequest.Referer = null;
			httpWebRequest.AllowAutoRedirect = true;
			httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
			httpWebRequest.Accept = "*/*";
			httpWebRequest.Proxy = null;
			httpWebRequest.KeepAlive = false;
			httpWebRequest.ProtocolVersion = HttpVersion.Version10;
			byte[] bytes = Encoding.UTF8.GetBytes(body);
			httpWebRequest.ContentLength = bytes.Length;
			using (Stream stream = httpWebRequest.GetRequestStream())
			{
				stream.Write(bytes, 0, bytes.Length);
				stream.Close();
			}
			try
			{
				HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
				Stream responseStream = httpWebResponse.GetResponseStream();
				using (StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8))
				{
					result = streamReader.ReadToEnd();
				}
				httpWebRequest.Abort();
				httpWebResponse.Close();
			}
			catch (WebException ex)
			{
				HttpWebResponse httpWebResponse2 = (HttpWebResponse)ex.Response;
				StreamReader streamReader2 = new StreamReader(httpWebResponse2.GetResponseStream(), Encoding.UTF8, detectEncodingFromByteOrderMarks: false);
				result = streamReader2.ReadToEnd();
			}
			return result;
		}

		public static byte[] DownloadFile(string url, string contentType = "application/x-zip-compressed", Action<double> acProcess = null)
		{
			HttpWebRequest httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
			httpWebRequest.ContentType = contentType;
			HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
			Stream responseStream = httpWebResponse.GetResponseStream();
			long contentLength = httpWebResponse.ContentLength;
			byte[] array = new byte[1024];
			int num = responseStream.Read(array, 0, array.Length);
			long num2 = 0L;
			List<byte> list = new List<byte>();
			while (num > 0)
			{
				num2 += num;
				if (num == array.Length)
				{
					list.AddRange(array);
				}
				else
				{
					byte[] array2 = new byte[num];
					Array.Copy(array, 0, array2, 0, num);
					list.AddRange(array2);
				}
				double obj = Math.Round((double)num2 * 100.0 / (double)contentLength, 2);
				acProcess?.Invoke(obj);
				num = responseStream.Read(array, 0, array.Length);
			}
			responseStream.Close();
			return list.ToArray();
		}

		public static byte[] RequestDownloadData2(string url)
		{
			try
			{
				RestClient client = new RestClient(url);
				RestRequest request = new RestRequest(url);
				return client.DownloadData(request);
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private static Tuple<RestClient, RestRequest> RestClientSet(string url, Method method, string body, bool isToken = true, bool isJson = true, bool keepAlive = true, Dictionary<string, string> dicHeader = null, int timeout = 3000)
		{
			RestClient restClient = new RestClient(url);
			RestRequest restRequest = new RestRequest();
			restRequest.Method = method;
			restRequest.Timeout =TimeSpan.FromMicroseconds( timeout);
			if (dicHeader != null)
			{
				foreach (string key in dicHeader.Keys)
				{
					restRequest.AddHeader(key, dicHeader[key]);
				}
			}
			if (keepAlive)
			{
				restRequest.AddHeader("Connection", "keep-alive");
			}
			if (isToken)
			{
				restClient.AddDefaultHeader("token", "");
			}
			switch (method)
			{
			case Method.Get:
				restRequest.AddHeader("Content-Type", "application/json");
				break;
			case Method.Post:
				if (isJson)
				{
					restRequest.AddHeader("Content-Type", "application/json");
					restRequest.AddParameter("application/json", body, ParameterType.RequestBody);
				}
				else
				{
					restRequest.AddHeader("Content-Type", "application/json");
					restRequest.AddParameter("application/x-www-form-urlencoded", body, ParameterType.RequestBody);
				}
				break;
			case Method.Put:
				restRequest.AddHeader("Content-Type", "application/json");
				break;
			case Method.Delete:
				restRequest.AddHeader("Content-Type", "application/json");
				break;
			default:
				restRequest.AddHeader("Content-Type", "application/json");
				break;
			}
			return new Tuple<RestClient, RestRequest>(restClient, restRequest);
		}

		public static async Task<RestResponse> RequestBehaviorAsync(string url, Method method, string body, bool isToken = true, bool isJson = true, bool keepAlive = true, Dictionary<string, string> dicHeader = null, int timeout = 30000)
		{
			Tuple<RestClient, RestRequest> clientRet = HttpUtil.RestClientSet(url, method, body, isToken, isJson, keepAlive, dicHeader, timeout);
			return await clientRet.Item1.ExecuteAsync(clientRet.Item2);
		}

		public static RestResponse RequestBehaviorSync(string url, Method method, string body, bool isToken = true, bool isJson = true, bool keepAlive = true, Dictionary<string, string> dicHeader = null, int timeout = 30000)
		{
			Tuple<RestClient, RestRequest> tuple = HttpUtil.RestClientSet(url, method, body, isToken, isJson, keepAlive, dicHeader, timeout);
			return tuple.Item1.Execute(tuple.Item2);
		}

		public static async Task<RestResponse> RequestBehaviorAsync(string url, Method method, string contentType, object body, bool isToken = true)
		{
			RestClient client = new RestClient(url);
			RestRequest request = new RestRequest
			{
				Method = method
			};
			if (isToken)
			{
				client.AddDefaultHeader("token", "");
			}
			if (method == Method.Post)
			{
				request.AddHeader("Content-Type", contentType);
				request.AddParameter("application/octet-stream", body, ParameterType.RequestBody);
			}
			else
			{
				request.AddHeader("Content-Type", contentType);
			}
			return await client.ExecuteAsync(request);
		}

		public static RestResponse RequestBehaviorSync(string url, Method method, string contentType, object body, bool isToken = true)
		{
			RestClient restClient = new RestClient(url);
			RestRequest restRequest = new RestRequest();
			restRequest.Method = method;
			if (isToken)
			{
				restClient.AddDefaultHeader("token", "");
			}
			if (method == Method.Post)
			{
				restRequest.AddHeader("Content-Type", contentType);
				restRequest.AddParameter("application/octet-stream", body, ParameterType.RequestBody);
			}
			else
			{
				restRequest.AddHeader("Content-Type", contentType);
			}
			return restClient.Execute(restRequest);
		}
	}
}
